La source du Mal

![Les deux serpents du logo python invitent Eve à manger la pomme d'Apple](/media/2020/python+mac.png)

La semaine avait plutôt bien commencé. Bien sûr, tout le retard accumulé sur le projet n'allait pas disparaître comme ça mais, quand même, pour une fois les choses donnaient l'impression d'avancer. Pour une fois, l'univers entier semblait avoir consenti à un léger répit pour redonner de l'espoir à la petite équipe du labo. Pour la première fois depuis quelque semaines, je faisais autre chose que harceler des gens par courriel pour obtenir des détails sur les solutions magiques qu'ils nous avaient fait miroiter au moment de déposer des demandes de financement pour le projet, découvrir et corriger une n<sup>ième</sup> incohérence dans le corpus voire une erreur d'encodage dramatique dans les fichier ou faire le bilan sur tout ce qui n'allait pas dans les tâches déjà entamées et parcourir avec crainte la longue liste de celles restantes. J'écrivais du code nécessaire pour le projet, j'entraînais le programme de reconnaissance de structure de texte par apprentissage automatique.

C'est le moment qu'a choisi Mon Chercheur pour débarquer dans le bureau. Il avait besoin de comparer la classification des articles de l'Encyclopédie par domaine de connaissance selon deux sources qui publiaient le texte. Il me montre rapidement comment il s'y prend : il utilise les pages web de chaque projet pour dresser les listes par domaine et essaye de copier-coller les résultats dans un fichier texte pour pouvoir ensuite effectuer les comparaisons. Ça marchait franchement pas si mal jusqu'à ce qu'il tombe sur sa majesté la Botanique, qui est venue titiller son sens de la ténacité avec sa cour de 4000 articles. Clairement, la méthode crapi-crapaud que j'te copie-colle le texte des pages web, ça allait bien deux minutes.

Mais comme tout n'est pas à jeter dans ce monde, les deux projets ont engagé chacun à un point de leur histoire des développeur·ses web compétentes qui ont naturellement séparé les données et leur présentation : le site web n'est qu'une jolie interface vide pour afficher des données bien rangées et exposées clairement dans une API (c'est un concept plus général, mais en gros dans le monde du web, c'est une couche intermédiaire qui fait le lien entre la page que le navigateur affiche et la base de donnée sur le serveur). Super ! J'expliquer ça à Mon Chercheur, je passe en console de développement du navigateur web de son MacBook (bin, oui, c'est un chercheur, il peut quand même pas utiliser autre chose qu'un MacBook, c'est une question de reconnaissance sociale : vous y croiriez, vous, à un·e graphiste sous autre chose qu'un Mac ? bin la recherche, c'est pareil, en dehors de la recherche en informatique, tout le monde doit avoir ça, je crois que ça doit être donné avec la thèse ou peut-être l'Habilitation à Diriger les Recherches). Je lui montre les requêtes qui sont faites, récupère l'URL de l'API et commence à jouer un peu avec pour lui montrer qu'en fait les données qui l'intéressent sont là. Pas encore sortie du bureau, le plan d'attaque était limpide : une requête sur chaque API avec `curl`, un tri puis une comparaison sur laquelle il faudrait peut-être montrer un tout petit peu de ruse, car il est impossible que les deux projets aient pris exactement les mêmes conventions en terme d'accentuation et de ponctuation mais globalement c'était un travail de 5mn. Environ. Las ! C'était compter sans toutes les horreurs que des systèmes fermés et pas faits pour être utilisés allaient dresser sur notre route.

<br>

Le logiciel `curl` pour celles et ceux qui ne connaîtraient pas, c'est tout simplement un client web, comme votre navigateur web, mais qui travaille de manière automatisable, ce qui en fait un super point de départ pour un script qui serait une chaîne de traitement destinée à récupérer des données dans une page comme par exemple, dans le cas qui nous intéresse, une API.

Bon, c'est hyper pratique, mais c'est un logiciel en ligne de commande : je ne m'attends pas à ce que Mon Chercheur apprenne à l'utiliser juste pour pouvoir comparer ses sources de l'Encyclopédie, surtout qu'il faut quand même ensuite comparer les données de chaque source et ça n'est pas son boulot.

## Un script vite-fait ?

Non, comme je l'ai écrit, j'ai juste à coder un script tout simple qui télécharge les données de chaque API avec `curl`, puis les filtre avec la commande `sort`. Quand on explique — moi la première — que la ligne de commande est simple, il ne s'agit pas de dogme. Intrinsèquement, la ligne de commande et plus particulièrement les structures et les opérateurs de contrôles sont des outils fantastiques parce qu'ils permettent de **composer** des programmes simples. Vous avez deux programmes pas trop durs à utiliser et en les combinant vous obtenez un truc génial qui correspond pile à votre besoin trop spécifique pour lequel personne n'aurait écrit un programme.

Oui, mais… mon script serait encore un outil en ligne de commande. Je peux le faire aussi simple que je veux (et, en l'occurrence, difficile de faire compliqué : vu le besoin, le script prend un argument unique, le domaine de connaissance à chercher et qui aurait dû être tappé deux fois, une fois sur le site web de chaque source), Mon Chercheur n'*arrivera* pas à l'utiliser. C'est à dire qu'il n'a aucun problème technique qui l'empêcherait de l'utiliser, qu'il n'a aucun problème cognitif pour apprendre à l'utiliser mais qu'il souffre du biais que «la ligne de commande c'est compliqué» qu'on voit répéter partout pour confisquer une réflexion sur la conception d'interfaces utilisateur (au sens large, interfaces textuelles, graphiques, sonores…) et la remplacer par un «débat» en réalité publicitaire sur les «mérites propres» de chaque OS au-delà des notions de libertés logicielles. Faque on oublie le script.

## Une petite GUI alors

Ça n'est pas grave, me suis-je alors dit, une petite interface graphique, c'est vite fait. Je me souvenais avoir bricolé rapidement des fenêtres de dialogue avec `gtkdialog` à une époque pour un projet. C'est un outil qui permet de donner une interface graphique à un script : des champs de saisie, des zones de textes, des boutons… tout ce dont il y a besoin pour représenter notre opération de recherche et de comparaison. Oui, sauf que dans `gtkdialog`, y a `gtk`, qui est une librairie graphique libre, ouverte, donc implémentable facilement partout, ce qui veut dire que bien sûr c'est la croix et la bannière pour l'utiliser sur les systèmes propriétaires comme Mac et Windows.

Une remarque encore une fois ici : beaucoup de gens essayent de présenter tous les systèmes d'exploitation comme des compétiteurs égaux se battant pour dominer le marché, chacun proposant ses propres produits de manière trompeusement avantageuse. Il n'en est rien, la nature même du logiciel libre est d'être diffusable, modifiable, etc. et de plus il n'y a pas de phénomène d'accumulation : il n'y a pas une entité «Linux» ou «BSD» qui propose un OS, une librairie graphique, un environnement de bureau. Non, il y a plein de projets, qui proposent des composants qui peuvent ensuite être réutilisés et combinés à leur guise par tous les autres. La lib graphique de Windows, je ne demande que ça d'apprendre à l'utiliser, sauf que je n'ai pas le droit légalement, Windows m'empêche de le faire sans leur payer des droits et je n'ai pas la possibilité techniquement, Windows ne me donne pas accès aux sources de leurs outils. Je dis, Windows, mais il en va évidemment de même pour Mac. Donc, ces firmes de logiciel propriétaire ne permettent pas de rentrer facilement sur le marché de leur OS (car c'est bien cela dont il s'agit, un OS crée un espace dans lequel apparaîtront naturellement des besoins qui ne demanderont qu'à être comblés par des projets de code — c'est pas un hasard si le dépôt de paquets de Mac s'appelle l'App **Store**), mais surtout ne rendent pas accessibles facilement les outils libres que d'autres auront développé (bin, oui, si tout le monde apprend à les utiliser, qu'est-ce qui les forcera à rester sur ce système et à pas essayer autre chose ?). Alors en écrivant tout ça et en me relisant j'ai vraiment l'impression de radoter mais j'en ai marre d'entendre que les logiciels libres sont durs à utiliser parce que pas disponibles (ou pas disponibles facilement) sous les OSs propriétaires. Non, ils ne sont pas compliqués à utiliser, ne devraient pas l'être et s'ils le sont la responsabilité en incombe uniquement aux OSs concernés.

## Aller, on se remet à Python

En même temps, c'est pas très grave, même si le shell était tout indiqué pour écrire cette GUI simple et faire appel à des outils en ligne de commande comme `curl` et `sort`, ça ne me fera pas de mal de refaire un peu de Python. C'est un langage vraiment chouette dans lequel il existe des tas de librairies pour faire des interfaces graphiques. Alors je lis un peu des avis, des comparatifs, je me mets en quête de la lib idéale qui me permettrait d'écrire mon code en Python, de le tester sur ma machine de développement sous Linux et de le faire tourner sur le MacBook de Mon Chercheur. Je finis par me fixer sur [wxWidget](https://wxwidgets.org/about/screenshots/), qui est employée notamment par des projets comme [Audacity](https://www.audacityteam.org/).

Bon, c'est une nouvelle librairie pour moi, y a forcément un peu de temps d'apprentissage, je lis des tutos, des exemples. Je bricoles mes premières tentatives simplistes juste pour m'assurer que ça marche et tester sous les deux systèmes (ah, oui, naturellement j'ai dû passer du temps aussi à m'installer une machine virtuelle sous MacOS pour pouvoir tester au fur et à mesure ce que je fais). Assez rapidement, j'ai un truc qui marche. Je commence à me demander comment je vais le distribuer simplement à Mon Chercheur. Oui, moi, je développe, j'écris et je compile le logiciel. Dans la machine virtuelle MacOS, j'ai installé de quoi compiler mon code, mais bien entendu, hors de question d'installer des outils de développements qu'il n'utilisera pas et lui paraîtront compliqués sur la machine de Mon Chercheur. Bin oui, si encore il s'agissait seulement de faire efficacement les choses. Mais non, en plus il faut que ça ait l'air simple de bout en bout pour pas l'effrayer, que ça prenne pas trop longtemps à installer parce que pendant ce temps-là lui ne bosse pas, il s'agit de faire une démonstration du «Cool» le plus absolu, comme un canard, l'air de rien au dessus de la surface, mais les papattes qui pédalent à fond en-dessous. Objectif : 7.2 Méga-Fonzie.

## L'enfer blanc imMACulé

Alors c'est le moment où je cherche comment on produit une «App», le format canonique pour distribuer un programme sous Mac. J'aime plutôt bien le concept, c'est un dossier, mais le système reconnaît l'extension `.app` et utilise une icône spéciale qu'il cherche à l'intérieur du dossier pour le représenter et associe comme comportement par défaut à un clic dessus de lancer le programme qu'il contient. Avec un peu de recherche, j'apprends que deux outils, `py2app` et `pyInstaller` me permettraient de faire ce que je veux.

En pratique, ça m'a pris pas mal de temps pour tester, tomber sur des erreurs bizarres, essayer d'en chercher les causes, réessayer, abandonner et re-tester plutôt l'autre. Dans l'idéal, j'aurais voulu pouvoir assembler le `.app` sur ma machine et l'envoyer sur une nouvelle machine virtuelle fraîche sans les outils de compilation sensée répliquer le plus fidèlement possible celle de Mon Chercheur. Ça n'a pas marché (un peu surprise, puisque ça génère des `.app`, je pensais que ça cross-compilait ce qu'il y avait besoin pour Mac), mais j'ai quand même réussi à trouver une configuration qui marche : je crée le `.app` sur ma machine virtuelle de développement, je la pousse sur un serveur qui sera accessible à Mon Chercheur, je le télécharge depuis l'autre machine virtuelle et je le lance pour tester. Bien sûr, j'ai dû trouver par hasard des options cruciales comme `-windowed` qui veut dire «ah oui crée moi un `.app` et puis c'est pour avoir une fenêtre graphique donc fais en sorte que ça marche», mentionnée dans aucun tutoriel pour utiliser `pyInstaller`.

Quand je dis «j'ai réussi», il ne s'agit pas pour autant d'un franc succès éclatant. Je télécharge, je clique dessus pour l'exécuter, le système me dispute parce que c'est un truc qui vient du web, ça pourrait être un virus, est-ce que je suis sûre que je veux l'exécuter (et quand je dis «oui», en fait blagounette, bin il refuse quand même). C'est reparti pour un petit temps de recherche pour comprendre et apprendre à contourner le pépin. C'est très simple, je ne suis pas une développeuse officielle certifiée par MacOS et mon programme n'a pas pu être vérifié comme «sûr». Comprendre «je n'ai pas créé de compte et fourni mes données à Apple pour pouvoir être identifiée clairement et que mon appli apparaisse dans l'App Store». Alors, bon, déjà ça ne correspond clairement pas à mes besoins : je veux juste mettre rapidement sur une machine à nous l'équivalent d'un mini-script. Mais surtout, je doute honnêtement que Apple ait vraiment envie d'avoir ses dépôts de paquets pollués chaque fois que n'importe qui a besoin de scripter un truc vite-fait.

Alors heureusement en vrai c'est complètement bénin, il suffit de trouver le bon menu caché quelque part dans les préférences systèmes pour autoriser manuellement l'exécution du programme. Mais une fois de plus, ça rend tout ça suspect et compliqué aux yeux de Mon Chercheur, qui en théorie devrait pouvoir faire ça tout seul, puisque, pour rappel, s'il utilise un Mac, c'est que c'est plus simple.

Mais ça n'est pas grave, parce qu'enfin j'ai trouvé. J'ai réussi. J'ai généré un programme au bon format qu'il suffit de télécharger puis de lancer sur le Mac de Mon Chercheur. Je le préviens, très contente de moi, que j'ai fini et qu'il va enfin pouvoir travailler à ses comparaisons. Je lui télécharge, l'ouvre et lui montre que ça marche (oui, c'est moi qui fais, hein, parce que c'est tellement simple, MacOS, qu'il ne sait pas juste aller télécharger un programme quelque part sur le web et cliquer sur un bouton). Il teste une recherche et… bien entendu le programme plante atrocement sur sa machine, là où il marchait parfaitement sur la mienne.

Je reprends le contrôle et me rends compte que le programme plante à cause de requêtes web qui échouent (les mêmes qui réussissaient parfaitement dans ma machine virtuelle puisqu'il s'agit du même programme). Aucune piste immédiate, je repars pour quelques heures de galère en annonçant à Mon Chercheur que je n'ai aucune idée sérieuse et que je ne vois pas *du tout* comment corriger l'erreur pour l'instant.

Après encore de longues heures de recherches, je finis par tomber sur une explication encore plus décevante que le problème lui-même. L'environnement Python compilé pour faire tourner l'application ne permet pas d'accéder aux certificats installés sur le système. Aller, encore un point technique rapide : le système utilisé pour «vérifier» les contenus sur le web est un système d'arborescence de confiance ou des entités vérifient des contenus et leur signe un certificat, qui à son tour permet d'en signer d'autre. Pour que ça marche, il faut naturellement connaître les racines du système (oui du coup c'est pas un arbre c'est une forêt puisqu'il y a plusieurs nœuds racine indépendants, qui sont ce qu'on appelle les autorités de certification). C'est un système très discutable mais qui en tout cas est celui déployé partout actuellement. Sauf que là, ce qui se passe, c'est que Mac garde jalousement ses certificats et ne laisse pas l'application Python les utiliser. C'est idiot, on ne va pas se mettre à distribuer (et donc à mettre à jour, dès que ça change…) un jeu de certificats à chaque appli qui a besoin de vérifier l'authenticité de contenus. C'est typiquement le genre de fonctionnalités qui doivent être factorisées et c'est pile le rôle de l'OS de fournir ça.

Encore de longues heures de recherche pour enfin tomber sur un correctif à l'arrache sur un coin de [github](https://github.com/pyinstaller/pyinstaller/wiki/Recipe-OpenSSL-Certificate) et finalement réussir à faire marcher ce satané truc même sur la machine de Mon Chercheur. Fuuuuu.

<br>

Comme le temps passe vite, avec tout ça j'ai perdu un peu plus d'une semaine. Pourquoi ai-je perdu autant de temps ? Certes, il y a eu un peu de temps d'apprentissage pour des outils que je n'avais pas encore beaucoup utilisés et qui ne sera pas vraiment perdu puisque ça me resservira plus tard. Mais la raison fondamentale de tout ce déploiement d'énergie, c'est que Mon Chercheur, contrairement à moi, utilise un système simple, MacOS. Un système qui ne lui a jamais permis de combiner facilement des opérations simples (lire une page web, comparer des données), ni ne lui a appris à utiliser des outils efficaces pour le faire comme la ligne de commande (une fois de plus, hein, je suis persuadée qu'on peut faire mieux que la ligne de commande, mais ça marche quand même drôlement bien et je n'ai pas encore vu proposer mieux). Son système ne met pas à sa disposition d'outils pratiques pour développer rapidement un programme pour compenser, décourage le fait d'en écrire pour lui et enfin, échoue à répondre à un besoin aussi basique que fournir des certificats SSL alors qu'il est de sa responsabilité. Être plus limité, ça ne veut pas dire être plus simple : un tractopelle est certainement plus difficile à conduire qu'une pelle, mais peut-on vraiment dire qu'une pelle est «plus simple» qu'un tractopelle ? Tu m'étonnes que c'est simple, si tu ne peux tout simplement pas faire les choses et que quelqu'un est obligé de les faire à ta place, tout est hyper simple. Il pourrait prendre une feuille de papier aussi, et je fais tout ce qu'il aurait fait sur un ordinateur à sa place.

Ce simple «script curl» est devenu un binaire de plus de 10Mo qui m'a coûté une semaine de temps de développement que je n'ai passée sur le projet pour lequel je suis payée. Alors on cherche des sous partout dans la recherche, on tire sur la corde tant et plus pour que tout ne tourne plus que par la seule bonne volonté des personnels des labos mais si on veut vraiment faire des économies, si on commençait par former les gens à utiliser des outils simples en réalité et pas seulement en apparence, gratuits et qui les rendent autonomes ?